﻿using System;
using System.Collections;
using System.Linq;
using System.Text;
using System.IO;

namespace Neural
{
    /// <summary>
    /// 
    /// Learning data converter class, converts collection of input files
    /// to appropriate form to use it in NeuralNet learning.
    /// 
    /// Author: harpserg@gmail.com
    /// 
    /// </summary>
    class LDConverter    
    {
        /// <summary>
        ///
        /// Конвертирует файл данных в формат, воспринимаемый встроенным методом обучения
        /// библиотеки FANN.
        /// 
        /// </summary>
        /// <param name="STR_L">количество чисел в статистической строке</param>
        /// <param name="ANSWER_L">количесто чисел в ответе( = количество нейронов результата)</param>
        /// <param name="strQuantity">количество строк, подаваемых на вход нейросети</param>
        /// <param name="predSteps">спустя сколько шагов вперед делаем прогноз</param>
        /// <param name="inFilePath">Имя входного файла.</param>
        public static void convertFile(int STR_L, int ANSWER_L, int strQuantity, int predSteps, string inFilePath)
        {
            int lines = countFileLines(inFilePath);
            int learningPairs = lines - (strQuantity + predSteps);
            //Console.WriteLine(learningPairs);
            if (learningPairs <= 0)
            {
                Console.WriteLine("File {0} is too short! It wouldn't be converted! :(", inFilePath);
                Console.WriteLine();
                return;
            }
            Console.WriteLine("File {0} in process.", inFilePath);
            StreamWriter outfile = new StreamWriter(genegateOutPath(STR_L, ANSWER_L, strQuantity, predSteps, inFilePath));
            outfile.WriteLine("{0} {1} {2}", learningPairs, STR_L * strQuantity, ANSWER_L);//заголовок файла в формате адаптированном для FANN

            TextFileReader infile = new TextFileReader(inFilePath);
            infile.skipNextLine();//пропускаем первую строку с метаданными

            Queue queue = new Queue(strQuantity + predSteps);
            for (int i = 0; i < strQuantity + predSteps - 1; i++) 
            {
                queue.Enqueue(infile.getNextLine());
            }
            for (int pair = 0; pair < learningPairs; pair++)
            {
                string lastline = infile.getNextLine();
                queue.Enqueue(lastline);
                int k = 0;
                string inline = "";
                foreach (string line in queue)
                {
                    if (k < strQuantity)
                        inline += line;
                    else
                        break;
                }
                outfile.WriteLine(inline);
                outfile.WriteLine(reduceAnswer(lastline));
                queue.Dequeue();
            }
            outfile.Close();
            Console.WriteLine("File {0} conversion success :)", inFilePath);
            Console.WriteLine();
        }

        public static void convertAllTXTFromDir(int STR_L, int ANSWER_L, int strQuantity, int predSteps, string dirPath)
        {
            foreach(string filepath in Directory.GetFiles(dirPath, "*.txt"))
            {
                convertFile(STR_L, ANSWER_L, strQuantity, predSteps, filepath);
            }
        }

        private static string genegateOutPath(int STR_L, int ANSWER_L, int strQuantity, int predSteps, string inFilePath) 
        {
            string name = String.Format("{0}_{1}_{2}_{3}_{4}", STR_L, ANSWER_L, strQuantity, predSteps, Path.GetFileNameWithoutExtension(inFilePath));
            string res = inFilePath.Replace(Path.GetFileNameWithoutExtension(inFilePath), name);
            res = Path.ChangeExtension(res, "fni");
            return res;
        }

        
        private static string reduceAnswer(string line) 
        {
            string res = "";
            string[] lineArr = line.Split(' ');
            res = String.Format("{0} {1} {2} {3} {4} {5}", lineArr[3], lineArr[4], lineArr[9], lineArr[10], lineArr[15], lineArr[16]);
            return res;
        }


        private static int countFileLines(string inFilePath)
        {
            int counter = 0;
            string line;
            try
            {
                System.IO.StreamReader file = new System.IO.StreamReader(inFilePath);
                while ((line = file.ReadLine()) != null)
                {
                    counter++;
                }
                file.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }           
            return counter;
        }
        
    }
}
